package com.numberma.userservice.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.numberma.userservice.Result.PageResult;
import com.numberma.userservice.Result.Result;
import com.numberma.userservice.Utils.*;
import com.numberma.userservice.constant.ActionName;
import com.numberma.userservice.constant.ErrorMsg;
import com.numberma.userservice.constant.LogConstant;
import com.numberma.userservice.constant.RoleConstant;
import com.numberma.userservice.entity.Dto.*;
import com.numberma.userservice.entity.Log;

import com.numberma.userservice.entity.Users;
import com.numberma.userservice.entity.VO.UserVo;
import com.numberma.userservice.mapper.UserMapper;


import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;


import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;


import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@GlobalTransactional
public class UserServiceImpl implements IUserService{
    @Autowired
    private ObjectMapper objectMapper; // Spring Boot自动配置的Jackson

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private permissionServiceClient permissionServiceClient;
    @Autowired
    private RabbitTemplate rabbitTemplate;


    /***
     * AI生成
     *  封装权限校验逻辑
     ***/

    private boolean checkPermission(Long UserId) {

        String roleCode = permissionServiceClient.getUserRole(UserId);
        String MyRoleCode = (String) ThroadLocal.get().get("roleCode");
        return Judge.Compare(MyRoleCode,roleCode);
    }
    public  boolean checkUpgradeToAdmin (String MyRole,String OldUserRole,String NewUserRole){
        if(MyRole.equals(RoleConstant.SUPER_ADMIN)
                && OldUserRole.equals(RoleConstant.USER)
                && NewUserRole.equals(RoleConstant.ADMIN)){
            return true;
        }


        return false;


    }
    public boolean checkDowngradeToUser (String MyRole,String OldUserRole,String NewUserRole){
        if(MyRole.equals(RoleConstant.SUPER_ADMIN)
                && OldUserRole.equals(RoleConstant.ADMIN)
                && NewUserRole.equals(RoleConstant.USER)){
            return true;
        }
        return false;


    }


   //finish
    @Override
    public Result register(Users user1)  {

        try {
            // 1. 验证手机号格式
            if (!CheckPhoneUtil.checkPhone(user1.getPhone())) {

                return Result.fail(ErrorMsg.INVALID_PHONE_FORMAT);
            }

            // 2. 验证密码格式
            if (!CheckPasswordUtil.CheckPassword(user1.getPassword())) {
                log.warn("密码格式无效: {}", user1.getPassword());
                return Result.fail(ErrorMsg.INVALID_PASSWORD_FORMAT);
            }

            // 3. 写入用户表
            userMapper.InsertUser(user1);
            Long userId = user1.getUserId();
            log.info("用户注册成功,用户ID:{}", userId);

            // 4. RPC调用权限服务
            permissionServiceClient.bindDefaultRole(userId);

            // 4. 发送MQ消息（放在最后，避免事务未提交就发送）
            Log event = LogBuildUtil.build(
                    userId,
                    LogConstant.Register,
                    IpUtils.getCurrentIp(),
                    objectMapper.writeValueAsString(user1),
                    LocalDateTime.now()
            );
            rabbitTemplate.convertAndSend("Log.exchange", "Logging.queue", event);

            return Result.ok();
        } catch (Exception e) {
            // 关键：手动触发事务回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.error(ErrorMsg.USER_LOGIN_ROLLBACK, e);
            return Result.fail(ErrorMsg.USER_REGISTER_FAILED);
        }


    }
   ///////////
    @Override
    public Result GetUser(Long UserId) {
        Log event = new Log();
        UserVo userVo = null;
        try {
            Map<String, Object> map = ThroadLocal.get();
            event = LogBuildUtil.build(
                    (Long) map.get("userId"),
                    LogConstant.Register,
                    IpUtils.getCurrentIp(),
                    LocalDateTime.now()
            );
            String roleCode = permissionServiceClient.getUserRole(UserId);
            String MyRoleCode = (String) map.get("roleCode");
            boolean result = Judge.Compare(MyRoleCode, roleCode);

            if (!result && !ThroadLocal.get().get("userId").equals(UserId)) {
                event.setDetail("无权限");

                return Result.fail("无权限");
            }
            Users user = userMapper.selectByUserId(UserId);
            if (user == null) {
                event.setDetail("用户不存在");

                return Result.fail(ErrorMsg.USER_NOT_FOUND);
            }

            userVo = new UserVo();
            BeanUtils.copyProperties(user, userVo);
            userVo.setRoleCode(roleCode);


            event.setDetail(objectMapper.writeValueAsString(user));
        } catch (Exception e) {
            event.setDetail(ErrorMsg.SERALIZE_FAILED);

        } finally {
            rabbitTemplate.convertAndSend("Log.exchange", "Logging.queue", event);
        }


        return Result.ok(userVo);


    }

    @Override
    public Result updateUser(Long userId, UserDto userDto) {
        try{
        Log event = new Log();
        String detail = null;
        if(userDto.getPhone()!= null && !CheckPhoneUtil.checkPhone(userDto.getPhone())){
            return Result.fail(ErrorMsg.INVALID_PHONE_FORMAT);
        }


        Map<String, Object> map = ThroadLocal.get();
       event =  LogBuildUtil.build((Long) map.get("userId"), ActionName.UPDATE_NAME, IpUtils.getCurrentIp(),LocalDateTime.now());
        String roleCode = permissionServiceClient.getUserRole(userId);
        String MyRole = (String) map.get("roleCode");

        boolean  result = Judge.Compare(MyRole,roleCode);
        if(!result&&!map.get("userId").equals(userId)){
            event.setDetail(ErrorMsg.NN_PERSSION);
            rabbitTemplate.convertAndSend("Log.exchange","Logging.queue",event);
            return Result.fail(ErrorMsg.NN_PERSSION);
        }
        if(userMapper.selectByUserId(userId) == null){
            event.setDetail(ErrorMsg.USER_NOT_FOUND);
            rabbitTemplate.convertAndSend("Log.exchange","Logging.queue",event);
            return Result.fail(ErrorMsg.USER_NOT_FOUND);
        }
        Users user = new Users();
        BeanUtils.copyProperties(userDto,user);
        user.setUserId(userId);
       // log.info("userDto:{},{},{}",userDto,roleCode.equals(RoleConstant.USER),userDto.getRole().equals(RoleConstant.ADMIN));
       //log.info("userId:{}",userId);
        Users oldUser = userMapper.selectByUserId(userId);
       // detail =

        userMapper.updateByUserId(user);
       // detail
            if(checkUpgradeToAdmin(MyRole,roleCode,userDto.getRole())&&userDto.getRole() != null){
                permissionServiceClient.upgradeToAdmin(userId);
            }
            else if(checkDowngradeToUser(MyRole,roleCode,userDto.getRole())&&userDto.getRole() != null){
                permissionServiceClient.downgradeToUser(userId);
            }
        return Result.ok("操作成功");}
        catch (Exception e){

            return Result.fail(ErrorMsg.USER_UPDATE_FAILED);
        }
    }

    @Override
    public Result resetPassword(UserIdPasswordDto userIdPasswordDto) {
        Log event = new Log();
        Long userId = userIdPasswordDto.getUserId();
        boolean result = checkPermission(userId);
        if(!result&&ThroadLocal.get().get("userId") != userId){
            return Result.fail(ErrorMsg.NN_PERSSION);
        }

        if (!CheckPasswordUtil.CheckPassword(userIdPasswordDto.getPassword())) {

            return Result.fail(ErrorMsg.INVALID_PASSWORD_FORMAT);
        }
        Users user = new Users();
        BeanUtils.copyProperties(userIdPasswordDto, user);
        userMapper.updatePasswordById(user);
//        event.setUserId(userId);
//        event.setAction("RESET_PASSWORD");
//        event.setIp(IpUtils.getCurrentIp());

        return Result.ok("重置密码成功");
    }

    @Override
    public Result login(UserLoginDto userLoginDto) {
         Log event = new Log();
         event = LogBuildUtil.build(null, ActionName.LOGIN_NAME, IpUtils.getCurrentIp(),LocalDateTime.now());
        //在数据库中查询用户是否存在
         Users user = new Users();

        user = userMapper.getPasswordByUsername(userLoginDto.getUsername());

        if(user == null) {
            return Result.fail(ErrorMsg.USER_NOT_FOUND);
        }
        if(!user.getPassword().equals(userLoginDto.getPassword())){
            return Result.fail(ErrorMsg.PASSWORD_ERROR);
        }
        //生成token
        Map<String, Object> map = new HashMap<String, Object>();

        map.put("userId", user.getUserId());
        map.put("roleCode", permissionServiceClient.getUserRole(user.getUserId()));
        String token =JwtUtil.CreateJwt(map);
        log.info("token:{}",token);

        try {
            event.setDetail(objectMapper.writeValueAsString(user));
        }
        catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        rabbitTemplate.convertAndSend("Log.exchange","Logging.queue",event);
        return Result.ok(ErrorMsg.LOGIN_SUCCESS);

    }

    @Override
    public PageResult getPageUsers(UserPageDto userPageDto) {
         String RoleCode =   ThroadLocal.get().get("roleCode").toString();
         Users user = new Users();
         BeanUtils.copyProperties(userPageDto,user);
        PageHelper.startPage(userPageDto.getPage(),userPageDto.getPageSize());
         if(RoleCode.equals(RoleConstant.SUPER_ADMIN)){
             Page<Users> page = userMapper.select();
             return new PageResult(page.getTotal(),page.getResult());

         }
         else if(RoleCode.equals(RoleConstant.ADMIN)){
             List<Long> userIds = permissionServiceClient.getUserIdsByRoleCode(RoleConstant.USER);

             Page<Users> page = userMapper.selectPageByUserId(userIds);
             return new PageResult(page.getTotal(),page.getResult());
         }
         List<Long> userIds = new  ArrayList<Long> ();
         userIds.add((Long) ThroadLocal.get().get("UserId"));
        Page<Users> page = userMapper.selectPageByUserId(userIds);
        return new PageResult(page.getTotal(),page.getResult());


    }


}
